package com.android.webserver.fwapi;


import java.net.URL;

import android.util.Log;

/**
 * Represent a single cookie
 */
class Cookie
{

	/**
	 * Null (unset) cookie age
	 */
	public static final int	NULL_AGE		= -1;

	/**
	 * Expired cookie
	 */
	public static final int	EXPIRED_AGE	= 0;

	private String					key;
	private String					value;
	private String					path;
	private String					domain;
	private String					version;
	private String					expires;
	private int							maxAge;
	private boolean					secure;
	private boolean					httpOnly;

	@SuppressWarnings("unused")
	private Cookie()
	{
	}

	/**
	 * Constructor
	 * 
	 * @param url
	 *          URL associated with this cookie
	 * @param key
	 *          Cookie name
	 * @param value
	 *          Cookie value
	 */
	public Cookie(URL url, String key, String value)
	{
		int slash = url.getFile().lastIndexOf("/");
		/*
		 * Save cookie name and content
		 */

		Log.i("WebServer", "url : " + url + " - " + url.getFile() + " - "
				+ url.getFile().lastIndexOf("/"));
		this.key = key;
		this.value = value;
		/*
		 * Domain defaults to hostname, path to the "directory" portion of the
		 * request, minus all text from the rightmost "/" character to the end of
		 * the string...
		 */
		this.path = slash < 1 ? url.getFile() : url.getFile().substring(0, slash);

		// this.domain = url.getHost();
		this.domain = null;

		this.version = null;
		this.expires = null;
		this.maxAge = NULL_AGE;

		this.secure = false;
		this.httpOnly = true;
	}

	/**
	 * Get cookie name
	 * 
	 * @return The cooke name
	 */
	public String getName()
	{
		return this.key;
	}

	/**
	 * Get cookie value (the cookie "text")
	 * 
	 * @return The value
	 */
	public String getValue()
	{
		return this.value;
	}

	/**
	 * Save the path
	 */
	public void setPath(String path)
	{
		this.path = path;
	}

	/**
	 * Get the path
	 * 
	 * @return The cooke path attribute value (null if none)
	 */
	public String getPath()
	{
		return this.path;
	}

	/**
	 * Save the expiration date
	 */
	public void setExpires(String expires)
	{
		this.expires = expires;
	}

	/**
	 * Get the expiration date
	 * 
	 * @return The expires attribute value (null if none)
	 */
	public String getExpires()
	{
		return this.expires;
	}

	/**
	 * Save the domain
	 */
	public void setDomain(String domain)
	{
		this.domain = domain;
	}

	/**
	 * Get the domain
	 * 
	 * @return The domain attribute value (null if none)
	 */
	public String getDomain()
	{
		return this.domain;
	}

	/**
	 * Save the version
	 */
	public void setVersion(String version)
	{
		this.version = version;
	}

	/**
	 * Get the cookie version
	 * 
	 * @return The version (null if none)
	 */
	public String getVersion()
	{
		return this.version;
	}

	/**
	 * Set the maximum age for this cookie
	 */
	public void setMaxAge(String maxAge)
	{
		try
		{
			this.maxAge = Integer.parseInt(maxAge);
		}
		catch (NumberFormatException ignore)
		{
		}
	}

	/**
	 * Get the maximum age for this cookie
	 */
	public int getMaxAge()
	{
		return this.maxAge;
	}

	/**
	 * Save security setting (true if cookie to be sent only via HTTPS)
	 */
	public void setSecure(boolean secure)
	{
		this.secure = secure;
	}

	public boolean getSecure()
	{
		return this.secure;
	}

	/**
	 * Save security setting (true if cookie must not be accessed by javascript)
	 */
	public void setHttpOnly(boolean httpOnly)
	{
		this.httpOnly = httpOnly;
	}

	public boolean getHttpOnly()
	{
		return this.httpOnly;
	}

	/**
	 * Equal strings?
	 * 
	 * @param a
	 *          String one
	 * @param b
	 *          String two
	 * @return true if both are null, or String "equals" is true
	 */
	private boolean stringEquals(String a, String b)
	{
		if ((a == null) && (b == null))
		{
			return true;
		}

		if ((a == null) || (b == null))
		{
			return false;
		}

		return a.equals(b);
	}

	/**
	 * Equal cookies?
	 * 
	 * @param cookie
	 *          for comparison
	 * @return true if cookie name, path, and domain are all equal
	 */
	public boolean equals(Cookie cookie)
	{
		if (!key.equals(cookie.getName()))
		{
			return false;
		}

		return stringEquals(path, cookie.getPath())
				&& stringEquals(domain, cookie.getDomain());
	}

	/**
	 * The <code>toString</code> method converts the cookie to the Set-Cookie
	 * value. This can be used to send the HTTP header to a client browser. This
	 * uses a format that has been tested with various browsers. This is required
	 * as some browsers do not perform flexible parsing of the Set-Cookie value.
	 * <p>
	 * Netscape and IE-5.0 cant or wont handle <code>Path</code> it must be
	 * <code>path</code> also Netscape can not handle the path in quotations such
	 * as <code>"/path"</code> it must be <code>/path</code>. This value is never
	 * in quotations.
	 * <p>
	 * For maximum compatibility cookie values are not transmitted in quotations.
	 * This is done to ensure that platforms like PHP, JavaScript and various
	 * others that don't comply with RFC 2109 can transparently access the sent
	 * cookies.
	 * 
	 * @return this returns a Set-Cookie encoding of the cookie
	 */
	public String toString()
	{
		return key + "=" + value + (version == null ? "" : "; version=" + version)
				+ (expires == null ? "" : "expires" + expires)
				+ (path == null ? "" : "; path=" + path)
				+ (domain == null ? "" : "; domain=" + domain)
				+ (maxAge < 0 ? "" : "; max-age=" + maxAge)
				+ (httpOnly ? "; HttpOnly" : "") + (secure ? "; secure;" : ";");
	}
}
